package cn.bitkit.component.redis;

import cn.bitkit.base.exception.BusinessAssert;
import cn.bitkit.base.util.LocalDateTimeUtil;
import cn.bitkit.base.util.RandomUtil;
import cn.bitkit.base.util.StringUtil;
import cn.bitkit.component.context.SpringContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * 用于订单号
 * type需要在这里定义
 * @author changbo
 */
@Slf4j
public class TenantOrderNoHelper {

    public static String getOrderNo(String tenant, String type) {
        return getOrderNo(tenant, type, LocalDateTime.now());
    }

    public static String getOrderNo(String tenant, String type, LocalDateTime date) {
        StringRedisTemplate stringRedisTemplate = SpringContext.getAssertedBean(StringRedisTemplate.class);
        //大于60秒的时间，不能使用，因为之前的key已经失效
        long milliSeconds = LocalDateTimeUtil.getMilliSeconds(date);
        if(milliSeconds - System.currentTimeMillis() > 2*60*1000){
            date = LocalDateTime.now();
        }
        String dateNum = LocalDateTimeUtil.toDateNum(date);
        long ms = milliSeconds%(24*60*60*1000)/10000;
        String msStr = StringUtil.leftPad(Long.toString(ms), '0', 4);
        String key = BasicRedisKey.BASIC_ORDER_NO + tenant + type + dateNum;
        int increment = RandomUtil.random(1, 9);
        stringRedisTemplate.opsForValue().setIfAbsent(key, "1000", Duration.ofSeconds(60));
        Long seq = stringRedisTemplate.opsForValue().increment(key, increment);
        BusinessAssert.isNotNull(seq, "订单号生成失败");
        String seqStr = StringUtil.leftPad(Long.toString(seq), '0', 6);
        //22位=dateNum-8位，type-4位，msStr-4位，seqStr-6位
        return dateNum + type + msStr + seqStr;
    }

    public static LocalDateTime getOrderTime(String orderNo){
        String time = orderNo.substring(0, 8);
        return LocalDateTimeUtil.parseDateNum(time);
    }
}
